package org.zjt.agent.bytebuddy.constructor;

import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.implementation.SuperMethodCall;
import net.bytebuddy.matcher.ElementMatchers;
import net.bytebuddy.utility.JavaModule;
import org.zjt.agent.bytebuddy.ConstructorInterceptor;
import org.zjt.agent.bytebuddy.Interceptor;
import org.zjt.agent.bytebuddy.binder.StringValueBinder;
import org.zjt.agent.bytebuddy.binder.ToStringInterceptor;

import java.lang.instrument.Instrumentation;

import static net.bytebuddy.matcher.ElementMatchers.*;

/**
 * @author <a href="juntao.zhang@bkjk.com">juntao.zhang</a>
 * @Description:
 * @Package org.zjt.agent.bytebuddy.binder
 * @date 2018/2/27 15:30
 * @see
 */
public class Agent {

    public static void premain(String arguments, Instrumentation instrumentation) {
        System.out.printf("----------premain-----arguments:%s-----instrumentation:%s------\n",arguments,instrumentation);
        new AgentBuilder.Default()
                .type(nameStartsWith(arguments).and(not(isInterface())).and(not(isStatic())))
                .transform(constructorTransformer()).with(new AgentBuilder.Listener(){

            @Override
            public void onDiscovery(String typeName, ClassLoader classLoader, JavaModule module, boolean loaded) {

            }

            @Override
            public void onTransformation(TypeDescription typeDescription, ClassLoader classLoader, JavaModule module, boolean loaded, DynamicType dynamicType) {

            }

            @Override
            public void onIgnored(TypeDescription typeDescription, ClassLoader classLoader, JavaModule module, boolean loaded) {

            }

            @Override
            public void onError(String typeName, ClassLoader classLoader, JavaModule module, boolean loaded, Throwable throwable) {
                throwable.printStackTrace();
            }

            @Override
            public void onComplete(String typeName, ClassLoader classLoader, JavaModule module, boolean loaded) {

            }
        }).installOn(instrumentation);
    }

    public static AgentBuilder.Transformer constructorTransformer() {
        return  (builder,typeDescription,classLoader,module) ->
                builder.constructor(ElementMatchers.takesArguments(2))
                        .intercept(SuperMethodCall.INSTANCE.andThen(MethodDelegation.withDefaultConfiguration()
                        .to(new ConstructorInterceptor())));
    }
}
